home *** CD-ROM | disk | FTP | other *** search
- #include "main.h"
- #include "patch.h"
-
- extern int isBackground;
- extern long oldWaitMouse, oldStillDown, oldAvail, oldDelay;
- extern int waitTrapOn, delayTrapOn;
-
- implemented( whichTrap ) {
- return( NGetTrapAddress( whichTrap, ToolTrap ) != NGetTrapAddress( UnImplTrapNum, ToolTrap ));
- }
-
- getMBarHeight() {
- return( implemented( ScriptsTrapNum ) ? GetMBarHeight() : MBarHeight );
- }
-
- /*******************************************************
- * *
- * InApplHeap should return true if the address passed it is between the beginning *
- * and end of the current application heap, and false otherwise. It can be used to *
- * detect whether an application patch has been installed on a trap. *
- * *
- * Note that as written, with the standard compiler glue, this depends on globals, *
- * which strictly speaking is not so cool. Instead, I could use the current stack *
- * pointer as an upper bound (although this may be a bad assumption on a possible *
- * virtual memory machine), and the HandleZone of a handle I have allocated as a *
- * lower bound. For example, the HandleZone of GetMHandle of the file menu. *
- * *
- *******************************************************/
-
- inApplHeap( addr )
- long addr;
- {
- return( addr > ( long )ApplicZone() && addr < ( long )GetApplLimit() );
- }
-
- /*******************************************************
- * *
- * This installs theCode as a patch on the trap, with the intermediate routine in *
- * the ptch resource of id how. flag specifies either OSTrap or ToolTrap. Within *
- * the application, patches override each other, rather than nesting. The routine *
- * specified by how is one of: *
- * *
- * replacePatchID: theCode entirely replaces the original trap code. *
- * filterPatchID: theCode is called before jumping to the original code. *
- * eitherPatchID: theCode is called, and the C return code specifies which. *
- * *
- * In the last case, the return code is either patchContinue or patchReturn. Note *
- * that the above routines only work for the stack based traps. If you use the *
- * replace routine, theCode should be a pascal function with the same arguments *
- * as the trap being patched, and return normally. If you use the filter routine, *
- * theCode should either be a C function with arguments reversed which returns *
- * normally, or a pascal function which returns abnormally (unlk, rts). If you *
- * use the either routine, the function should be in pascal, and depending on the *
- * result returned in d0, either return normally or abnormally. *
- * *
- *******************************************************/
-
- installPatch( trap, flag, theCode, how )
- long theCode;
- int trap, how, flag;
- {
- patchHandle thePatchHand;
- patchPtr thePatch;
- long original, myA5, oldPatch;
-
- oldPatch = NGetTrapAddress( trap, flag );
- if( inApplHeap( oldPatch )) {
- original = (( patchPtr )oldPatch )->original;
- } else {
- original = oldPatch;
- oldPatch = NULL;
- }
- if( !oldPatch || (( patchPtr )oldPatch )->patch != theCode ) {
- thePatchHand = ( patchHandle )GetResource( 'ptch', how );
- DetachResource( thePatchHand );
- HLock( thePatchHand );
- thePatch = *thePatchHand;
- asm {
- move.l a5,myA5
- }
- thePatch->count = 1;
- thePatch->myA5 = myA5;
- thePatch->patch = theCode;
- thePatch->original = original;
- thePatch->oldPatch = oldPatch;
- NSetTrapAddress( thePatch, trap, flag );
- } else thePatch->count++;
- }
-
- /*******************************************************
- * *
- * This removes the most recent patch on trap, where flag is as above. If the last *
- * patch using the particular intermediate routine is removed, it is disposed of. *
- * The initial check allows this to be called more times than strictly neccessary, *
- * but one should be *very* careful when doing this. *
- * *
- *******************************************************/
-
- removePatch( trap, flag )
- int trap, flag;
- {
- patchHandle thePatchHand;
- patchPtr thePatch;
-
- thePatch = ( patchPtr )NGetTrapAddress( trap, flag );
- /* if( inApplHeap( thePatch ))
- */ if( ! --( thePatch->count )) {
- if( thePatch->oldPatch ) NSetTrapAddress( thePatch->oldPatch, trap, flag );
- else NSetTrapAddress( thePatch->original, trap, flag );
- thePatchHand = ( patchHandle )RecoverHandle( thePatch );
- DisposHandle( thePatchHand );
- }
- }
-
- /*******************************************************
- * *
- * *
- *******************************************************/
-
- doDelay( numTicks, finalTicks )
- long numTicks, *finalTicks;
- {
- long ticks, endTicks;
- int diff;
-
- if( isBackground )
- {
- ticks = TickCount();
- endTicks = ticks + numTicks;
- while(( diff = endTicks - ticks ) > 0 ) {
- doBackground( diff, noGray, NULL );
- ticks = TickCount();
- }
- *finalTicks = ticks;
- return( *finalTicks );
- }
- else Delay( numTicks, finalTicks );
- }
-
- doDelayTrap()
- {
- long finalTicks, numTicks;
- asm {
- movem.l d3-d7/a2-a5,-(sp)
- move.l CurrentA5,a5
- }
- if( isBackground )
- {
- asm {
- move.l a0,numTicks
- }
- doDelay( numTicks, &finalTicks );
- asm {
- move.l finalTicks,d0
- movem.l (sp)+,d3-d7/a2-a5
- unlk a6
- rts
- }
- }
- else asm {
- move.l oldDelay,a1
- movem.l (sp)+,d3-d7/a2-a5
- unlk a6
- jmp (a1)
- }
- }
-
- doWaitMouse()
- {
- int temp;
- asm {
- movem.l d0-d7/a1-a5,-(sp)
- move.l CurrentA5,a5
- }
- doBackground( lotsElseToDo, noGray, NULL );
- asm {
- move.l oldWaitMouse,a0
- movem.l (sp)+,d0-d7/a1-a5
- unlk a6
- jmp (a0)
- }
- }
-
- doWaitClean()
- {
- int temp;
- asm {
- movem.l d0-d7/a1-a5,-(sp)
- move.l CurrentA5,a5
- }
- doBackground( lotsElseToDo, noGray, NULL );
- asm {
- move.l oldStillDown,a0
- movem.l (sp)+,d0-d7/a1-a5
- unlk a6
- jmp (a0)
- }
- }
-
- doAvail()
- {
- int temp;
- asm {
- movem.l d0-d7/a1-a5,-(sp)
- move.l CurrentA5,a5
- }
- doBackground( lotsElseToDo, noGray, NULL );
- asm {
- move.l oldAvail,a0
- movem.l (sp)+,d0-d7/a1-a5
- unlk a6
- jmp (a0)
- }
- }
-
- pascal long doDragGray( startRgn, startPt, limitRect, slopRect, axis )
- RgnHandle startRgn;
- Point startPt;
- Rect *limitRect, *slopRect;
- int axis;
- {
- long result;
-
- asm {
- movem.l d0-d7/a1-a5,-(sp)
- move.l CurrentA5,a5
- }
- setDragPat( gray );
- result = doDragTheRgn( startRgn, startPt, limitRect, slopRect, axis );
- asm {
- movem.l (sp)+,d0-d7/a1-a5
- unlk a6
- move.l (sp)+,a0
- move.l result,(sp)
- jmp (a0)
- }
- }
-
- installDelayTrap() {
- if( !delayTrapOn ) {
- oldDelay = NGetTrapAddress( DelayTrapNum, OSTrap );
- NSetTrapAddress( doDelayTrap, DelayTrapNum, OSTrap );
- }
- ++delayTrapOn;
- }
-
- removeDelayTrap() {
- if( delayTrapOn == 1 )
- NSetTrapAddress( oldDelay, DelayTrapNum, OSTrap );
- if( delayTrapOn > 0 ) --delayTrapOn;
- }
-
- installWaitTrap() {
- if( !waitTrapOn ) {
- oldStillDown = NGetTrapAddress( StillDownTrapNum, ToolTrap );
- NSetTrapAddress( doWaitClean, StillDownTrapNum, ToolTrap );
- }
- ++waitTrapOn;
- }
-
- removeWaitTrap()
- {
- if( waitTrapOn == 1 )
- NSetTrapAddress( oldStillDown, StillDownTrapNum, ToolTrap );
- if( waitTrapOn > 0 ) --waitTrapOn;
- }
-
- installAvailTrap() {
- oldAvail = NGetTrapAddress( AvailTrapNum, ToolTrap );
- NSetTrapAddress( doAvail, AvailTrapNum, ToolTrap );
- }
-
- removeAvailTrap() {
- NSetTrapAddress( oldAvail, AvailTrapNum, ToolTrap );
- }